package first.group.ssh.packet;

import first.group.ssh.SSHConsts;
import first.group.ssh.globalstate.GlobalState;
import first.group.ssh.globalstate.GlobalStateParser;
import first.group.ssh.packet.reader.BooleanReader;
import first.group.ssh.packet.reader.StringReader;
import first.group.ssh.packet.writer.BooleanWriter;
import first.group.ssh.packet.writer.StringWriter;
import java.io.IOException;
import java.nio.ByteBuffer;

public class GlobalRequestPacket extends Packet {

    public final String name;
    public final boolean wantReply;
    public final GlobalState.RequestPacket<? extends GlobalState> packet;

    public GlobalRequestPacket(String name, boolean wantReply, GlobalState.RequestPacket<? extends GlobalState> packet) {
        super(SSHConsts.SSH_MSG_GLOBAL_REQUEST);
        this.name = name;
        this.wantReply = wantReply;
        this.packet = packet;
    }

    public static PacketParser<GlobalRequestPacket> PARSER = new GlobalRequestPacket.Parser();

    private static class Parser extends PacketParser<GlobalRequestPacket> {

        @Override
        @SuppressWarnings("unchecked")
        public GlobalRequestPacket parse(ByteBuffer buffer) throws IOException {
            var name = StringReader.readString(buffer);
            if (name == null) {
                return null;
            }
            var wantReply = BooleanReader.readBoolean(buffer);
            if (wantReply == null) {
                return null;
            }
            GlobalState.RequestPacket<? extends GlobalState> packet = null;
            if (GlobalStateParser.isSupported(name)) {
                packet = GlobalStateParser.parseRequest(name, wantReply, buffer);
                if (packet == null) {
                    return null;
                }
            }
            return new GlobalRequestPacket(name, wantReply, packet);
        }
    }

    @Override
    public void write(ByteBuffer buffer) {
        StringWriter.writeString(buffer, name);
        BooleanWriter.writeBoolean(buffer, wantReply);
        packet.write(buffer);
    }
}
